/*
 * Copyright 2012 Marsrutai.lt
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lt.marsrutai.mobile.android.adapter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedSet;

import lt.marsrutai.mobile.android.R;
import lt.marsrutai.mobile.android.model.DayGroup;
import lt.marsrutai.mobile.android.model.enums.WeekdayType;
import lt.marsrutai.mobile.android.util.StringUtils;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;

/**
 * Provides tab information for a particular {@link DayGroup} and it's related arrival times
 * 
 * @author Justas
 */
public class StopTimesTabInfoProvider extends TabInfoProvider {

    /**
     * If the day group has to display more days than is specified, short day
     * names will be used.
     */
    private static final int DAY_GROUP_LONG_NAMES_THRESHOLD = 2;

    private static final WeekdayType[] WORK_DAYS = { 
            WeekdayType.MONDAY, 
            WeekdayType.TUESDAY, 
            WeekdayType.WEDNESDAY,
            WeekdayType.THURSDAY, 
            WeekdayType.FRIDAY };

    private static final WeekdayType[] WEEKEND = { WeekdayType.SATURDAY, WeekdayType.SUNDAY };

    public StopTimesTabInfoProvider(Class<? extends Fragment> fragmentClass, Bundle bundle, Context context, DayGroup dayGroup) {
        super(fragmentClass, bundle, toString(context, dayGroup));
    }
    
    private static String toString(Context context, DayGroup dayGroup) { 
        if (dayGroup.containsAll(Arrays.asList(WORK_DAYS)) && dayGroup.containsAll(Arrays.asList(WEEKEND))) {
            return context.getString(R.string.all_days);
        }
        else if (dayGroup.containsAll(Arrays.asList(WORK_DAYS)) && dayGroup.size() == WORK_DAYS.length) {
            return context.getString(R.string.workdays);
        }
        else if (dayGroup.containsAll(Arrays.asList(WEEKEND)) && dayGroup.size() == WEEKEND.length) {
            return context.getString(R.string.weekend);
        }
        else {
            List<SortedSet<WeekdayType>> consecutiveDays = dayGroup.getConsecutiveDays();
            List<String> stringParts = new ArrayList<String>();
            
            // If day group contains more than x days, use short names
            boolean useShortDayNames = dayGroup.size() > DAY_GROUP_LONG_NAMES_THRESHOLD && consecutiveDays.size() > 1;
            
            for (SortedSet<WeekdayType> days : consecutiveDays) {
                switch (days.size()) {
                case 1:
                    stringParts.add(resolveDayName(context, days.first().toString(), useShortDayNames));
                    break;
                case 2:
                    stringParts.add(String.format("%s, %s", 
                            resolveDayName(context, days.first().toString(), useShortDayNames),
                            resolveDayName(context, days.last().toString(), useShortDayNames)));
                    break;
                default:
                    stringParts.add(String.format("%s - %s", 
                            resolveDayName(context, days.first().toString(), useShortDayNames),
                            resolveDayName(context, days.last().toString(), useShortDayNames)));

                }
            }
            
            return StringUtils.join(stringParts, ", ");
        }
    }

    /**
     * Searches for string resources with the provided <code>name</code> or
     * <code>name_short</code>, depending on whether
     * <code>useShortDayNames</code> flag is <code>false</code> or <code>true</code>
     * 
     * @param name
     * @param useShortDayNames
     * @return Localized day name
     */
    private static String resolveDayName(Context context, String name, boolean useShortDayNames) {
        String resourceName = name + (useShortDayNames ? "_short" : StringUtils.EMPTY);
        int id = context.getResources().getIdentifier(resourceName, "string", context.getPackageName());

        if (id == 0) {
            throw new IllegalArgumentException("String resource with name '" + resourceName + "' is not defined.");
        }
        
        return context.getString(id);
    }

}
